/**
 *
 */
package rs.fon.rapidminer.operator.learner.tree;
import rs.fon.rapidminer.process.annotation.Parameter;
import com.rapidminer.example.ExampleSet;
import com.rapidminer.example.Attribute;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

import com.rapidminer.example.Attribute;
import com.rapidminer.example.Example;
import com.rapidminer.example.set.Partition;
import rs.fon.rapidminer.operator.learner.tree.SplittedExampleSet;

import rs.fon.rapidminer.process.annotation.Parameter; 

/**
 * @author Nikola
 *
 */
public class BinaryCategoricalPossibleSplit extends AbstractPossibleSplit {
    
 
   
    @Override
    public Object DoWork(ExampleSet exampleSet, List<rs.fon.rapidminer.process.Parameter> parameters, boolean [] attributesForSplitting, double insignificanceParameter, int depth)
    {       
        List<SplittedExampleSet> sviSplitedi = new LinkedList<SplittedExampleSet>();
      
      
      
        int i=0;
     
       for(Attribute attribute : exampleSet.getAttributes())
        {
        	if (attribute.isNominal()){
        		if(attributesForSplitting[i])
        		{
                   ExampleSet trainingSet = (ExampleSet)exampleSet.clone();
                    LinkedList<SplittedExampleSet>  binarySplitList = this.Split(trainingSet, attribute);   
                    sviSplitedi.addAll(binarySplitList);
        	    }
           
        	}
        	 i++;
        }
       
        return sviSplitedi;
    }
   
   
    public  LinkedList<SplittedExampleSet> Split(ExampleSet exampleSet, Attribute attribute) {
       
       
        LinkedList<SplittedExampleSet> binarySplitList  =  new LinkedList<SplittedExampleSet>();
        int[] elements = new int[exampleSet.size()];
        for (int r =0;r<elements.length; r++)
            elements[r] = 1;
       
        LinkedList<String> categories =getAllCategories(exampleSet, attribute);
       
        //StringBuffer combination;
        int index;
        int[] indices;  //Kreira kombinacije svih kategorija i stavlja ih u levu granu
        LinkedList<String> combination = new LinkedList<String>();
       
        for(int u=1; u<categories.size();u++){
       
        CombinationGenerator x = new CombinationGenerator (categories.size(), u);
        while (x.hasMore ()) {
          combination = new LinkedList<String>();
          indices = x.getNext ();
          for (int i = 0; i < indices.length; i++) {
              index = indices[i];
            combination.add(categories.get(index)); // Kreirana kombinacija od u kategorija
          }
          
        
          Iterator<Example> reader = exampleSet.iterator();
            int i = 0;
            while (reader.hasNext()) {
                Example example = reader.next();
                String currentValue = example.getValueAsString(attribute);
                if (inList(currentValue, combination))
                    elements[i] = 0;
                i++;
               
            }
                     
            Partition partition = new Partition(elements, 2);
            
            SplittedExampleSet splitted =new SplittedExampleSet(exampleSet, partition);
            splitted.setAttribute(attribute);
            binarySplitList.add(splitted);
           
            elements = new int[exampleSet.size()];
            for (int r =0;r<elements.length; r++)
                elements[r] = 1;
          }
        }
       
       
       
       
       
      
        return binarySplitList;
    }
   
    public  LinkedList<String> getAllCategories(ExampleSet exampleSet, Attribute attribute) {
        LinkedList<String> allCategoryList  =  new LinkedList<String>();
   
       
        Iterator<Example> reader = exampleSet.iterator();
       
        while (reader.hasNext()) {
            Example example = reader.next();
            String currentValue = example.getValueAsString(attribute);
            if (!inList(currentValue,allCategoryList))
                allCategoryList.add(currentValue);
        }
       
        //return new SplittedExampleSet(exampleSet, partition);
        return allCategoryList;
    }
   
    public  boolean inList(String category,List<String> allCategoryList) {
       
        for(int i =0; i<allCategoryList.size();i++)
        {
            if (allCategoryList.get(i).equals(category))
                return true;
         
        }
       
       return false;
    }
   
   
   
}
